package com.deuwise.system.service.impl;

import com.deuwise.common.utils.FileHelperUtils;
import com.deuwise.common.utils.UploadProperties;
import com.deuwise.common.utils.sqlhelper.SqlUtils;
import com.deuwise.system.entity.LogDO;
import com.deuwise.system.service.LogDoService;
import com.deuwise.system.mapper.LogDoMapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import javax.annotation.Resource;
import java.io.*;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.Statement;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * Syslog 接口实现类
 *
 * @author deuwise
 * @date 2018-11-09 17:12:43
 **/
@Service
public class LogDoServiceImpl extends ServiceImpl<LogDoMapper, LogDO> implements LogDoService {

    Logger logger = LoggerFactory.getLogger(LogDoServiceImpl.class);
    @Value("${spring.datasource.driverClassName}")
    private String jdbcDriver;

    @Value("${spring.datasource.druid.first.url}")
    private String jdbcUrl;
    @Resource
    private UploadProperties uploadProperties;

    @Value("${spring.datasource.druid.first.username}")
    private String jdbcUserName;

    @Value("${spring.datasource.druid.first.password}")
    private String jdbcPassword;

    @Override
    public String backUpLog(boolean isJob) {
        try {
            File file = new File(uploadProperties.getBasePath());
            if (!file.exists()) {
                file.mkdir();
            }
            Format f = new SimpleDateFormat("yyyyMMddHmmss");
            Date date = new Date();
            String fileName = "日志";
            String logTableName = "sys_log";
            if (isJob) {
                fileName = "任务日志";
                logTableName = "sys_job_run_log";
            }
            File dataFile = null;
            FileWriter dataFw =null;
            if (jdbcDriver.contains("oracle")) {
                Class.forName(jdbcDriver);
                Connection con = DriverManager.getConnection(jdbcUrl, jdbcUserName, jdbcPassword);
                Statement statement = con.createStatement();

                String dataStr = f.format(date) + "oracle" + fileName + "数据" + ".sql";
                System.out.println("文件路径:"+uploadProperties.getBasePath() + dataStr);
                dataFile = new File(uploadProperties.getBasePath()  + dataStr);
                try {
                    if(!dataFile.getParentFile().exists()){
                        System.out.println("父文件夹不存在，创建之");
                        dataFile.getParentFile().mkdirs();
                    }
                    if (!dataFile.exists()) {
                        /* 创建文件*/
                        dataFile.createNewFile();
                    }
                     dataFw = new FileWriter(dataFile, true);
                }catch (Exception ex){
                    System.out.println("创建文件写入出错"+ex.toString());
                }
                try {
                    String insertSqlStr = SqlUtils.genOracleInsertInto(logTableName, "", statement);
                    dataFw.write(insertSqlStr);
                    dataFw.flush();
                    dataFw.close();
                    statement.close();
                    con.close();
                    /** 压缩方法2  */
                    List<File> fileList = new ArrayList<>();
                    //获取日志文件备份
                    File fileLog = null;
                    String backlogFile = backUpLogFile();
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(backlogFile)) {
                        fileLog = new File(backlogFile);
                        if (fileLog.exists()) {
                            fileList.add(fileLog);
                        }
                    }
                    if (dataFile != null) {
                        fileList.add(dataFile);
                    }
                    FileOutputStream fos2 = new FileOutputStream(new File(uploadProperties.getBasePath() + f.format(date) + fileName + "备份" + ".zip"));
                    try {
                        FileHelperUtils.toZip(fileList, fos2);
                        dataFile.delete();
                        if (fileLog != null) {
                            fileLog.delete();
                        }
                        fos2.close();
                    } catch (Exception ex) {
                        System.out.println("压缩出错了1"+ex.toString());
                        logger.error("压缩" + fileName + "脚本失败" + ex.toString());
                        return "";
                    }
                    return uploadProperties.getBasePath() + f.format(date) + fileName + "备份" + ".zip";
                } catch (Exception e) {
                    System.out.println("压缩出错了2"+e.toString());
                    logger.error("操作备份出错了"+e.toString());
                    e.printStackTrace();
                }
            } else if (jdbcDriver.contains("mysql")) {
                Class.forName(jdbcDriver);
                Connection con = DriverManager.getConnection(jdbcUrl, jdbcUserName, jdbcPassword);

                Statement statement = con.createStatement();

                DatabaseMetaData dbmd = con.getMetaData();

                dataFile = new File(uploadProperties.getBasePath() + f.format(date) + "mysql数据" + ".sql");
                if (!dataFile.exists()) {
                    /* 创建文件*/
                    dataFile.createNewFile();
                }
                try {
                    dataFw = new FileWriter(dataFile, true);
                    String insertSqlStr = SqlUtils.getMysqlInsertSql(statement, logTableName, "");
                    dataFw.write(insertSqlStr);
                    dataFw.flush();
                    dataFw.close();
                    statement.close();
                    con.close();
                    /** 压缩方法2  */


                    List<File> fileList = new ArrayList<>();
                    //获取日志文件备份
                    File fileLog = null;
                    String backlogFile = backUpLogFile();
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(backlogFile)) {
                        fileLog = new File(backlogFile);
                        if (fileLog.exists()) {
                            fileList.add(fileLog);
                        }
                    }
                    if (dataFile != null) {
                        fileList.add(dataFile);
                    }
                    FileOutputStream fos2 = new FileOutputStream(new File(uploadProperties.getBasePath() + f.format(date) + "mysql" + fileName + "备份" + ".zip"));
                    try {
                        FileHelperUtils.toZip(fileList, fos2);
                        dataFile.delete();
                        if (fileLog != null) {
                            fileLog.delete();
                        }
                        fos2.close();
                    } catch (Exception ex) {
                        System.out.println("压缩mysql出错3"+ex.toString());
                        logger.error("压缩mysql" + fileName + "备份失败" + ex.toString());
                        return "";
                    }
                    return uploadProperties.getBasePath() + f.format(date) + "mysql" + fileName + "备份" + ".zip";
                } catch (Exception e) {
                    System.out.println("操作备份出错了1"+e.toString());
                    logger.error("操作备份出错了"+e.toString());
                    e.printStackTrace();
                }

            }else if(jdbcDriver.contains("postgresql")){
                Class.forName(jdbcDriver);
                Connection con = DriverManager.getConnection(jdbcUrl, jdbcUserName, jdbcPassword);

                Statement statement = con.createStatement();

                DatabaseMetaData dbmd = con.getMetaData();

                dataFile = new File(uploadProperties.getBasePath() + f.format(date) + "postgresql数据" + ".sql");
                if (!dataFile.exists()) {
                    /* 创建文件*/
                    dataFile.createNewFile();
                }
                try {
                    dataFw = new FileWriter(dataFile, true);
                    String insertSqlStr = SqlUtils.getPostgresInsertSql(statement, logTableName, "");
                    dataFw.write(insertSqlStr);
                    dataFw.flush();
                    dataFw.close();
                    statement.close();
                    con.close();
                    /** 压缩方法2  */


                    List<File> fileList = new ArrayList<>();
                    //获取日志文件备份
                    File fileLog = null;
                    String backlogFile = backUpLogFile();
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(backlogFile)) {
                        fileLog = new File(backlogFile);
                        if (fileLog.exists()) {
                            fileList.add(fileLog);
                        }
                    }
                    if (dataFile != null) {
                        fileList.add(dataFile);
                    }
                    FileOutputStream fos2 = new FileOutputStream(new File(uploadProperties.getBasePath() + f.format(date) + "postgresql" + fileName + "备份" + ".zip"));
                    try {
                        FileHelperUtils.toZip(fileList, fos2);
                        dataFile.delete();
                        if (fileLog != null) {
                            fileLog.delete();
                        }
                        fos2.close();
                    } catch (Exception ex) {
                        System.out.println("压缩postgresql出错3"+ex.toString());
                        logger.error("压缩postgresql" + fileName + "备份失败" + ex.toString());
                        return "";
                    }
                    return uploadProperties.getBasePath() + f.format(date) + "postgresql" + fileName + "备份" + ".zip";
                } catch (Exception e) {
                    System.out.println("操作备份出错了1"+e.toString());
                    logger.error("操作备份出错了"+e.toString());
                    e.printStackTrace();
                }
            }
        } catch (Exception ex) {
            System.out.println("操作备份出错了2"+ex.toString());
            logger.error(ex.toString());
        }
        return null;
    }

    /**
     * 备份日志文件
     *
     * @return
     */
    public String backUpLogFile() {
        //获取跟目录
        Format f = new SimpleDateFormat("yyyyMMddHmmss");
        Date date = new Date();
        File dataFile = null;
        File path = null;
        try {
            String location = "";
            //判断系统
            String os = System.getProperty("os.name");
            System.out.println("系统"+os);
            if (os.toLowerCase().startsWith("win")) {
                path = new File(ResourceUtils.getURL("").getPath());
            } else {
                System.out.println("linux获取目录");
                path = new File(ResourceUtils.getURL("classpath:").getPath());

            }
        } catch (Exception e) {
            System.out.println("服务器获取目录失败");
            logger.error("操作备份出错了3"+e.toString());
            e.printStackTrace();
        }
        if (!path.exists()) {
            path = new File("");
        }
        String logPath = FileHelperUtils.getLogSavePath();
        String pathStr = path.getAbsolutePath() + "/" + logPath;
        File dir = new File(pathStr);
        if (!dir.exists()) {
            logger.error("日志文件不存在");
            System.out.println("不存在");
        }

        if (!dir.isDirectory()) {
            logger.error("日志文件目录不存在");
            System.out.println("不存在目录");
        }

        Collection<File> list = org.apache.commons.io.FileUtils.listFiles(dir, FileFilterUtils.suffixFileFilter("log"), FileFilterUtils.suffixFileFilter(""));
        List<File> fileList = new ArrayList<>();
        for (File file : list) {
            fileList.add(file);
        }
        try {
            FileOutputStream fos2 = new FileOutputStream(new File(uploadProperties.getBasePath() + f.format(date) + "日志文件" + ".zip"));
            FileHelperUtils.toZip(fileList, fos2);
            fos2.close();
            return uploadProperties.getBasePath() + f.format(date) + "日志文件" + ".zip";
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            logger.error("压缩日志文件出错" + e.toString());
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("压缩日志文件出错" + e.toString());
        }
        return "";

    }
}